package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/tebeka/selenium"
	"github.com/tebeka/selenium/chrome"
	"go_19/core"
	"go_19/global"
	"net"
	"time"
)

var (
	DB1 *gorm.DB
)

type ApolloUsers struct {
	Id       int    `gorm:"column:Id" json:"Id"`
	Username string `gorm:"column:Username" json:"Username"`
	Password string `gorm:"column:Password" json:"Password"`
}

func main() {
	core.EmptyCli()
	if global.GVA_CONFIG.ApolloLogin.UserName == "apollo" {
		initDb()
	}
	wd, driverClean := initDriver()
	//fmt.Println("1", global.GVA_CONFIG.ApolloLogin.Host)
	wd.Get(global.GVA_CONFIG.ApolloLogin.Host)
	time.Sleep(1 * time.Second)
	loc_user, _ := wd.FindElement(selenium.ByXPATH, "//*[@id=\"login-form\"]/div[1]/input")
	loc_pwd, _ := wd.FindElement(selenium.ByXPATH, "//*[@id=\"login-form\"]/div[2]/input")
	loc_submit, _ := wd.FindElement(selenium.ByXPATH, "//*[@id=\"login-submit\"]")
	loc_user.SendKeys(global.GVA_CONFIG.ApolloLogin.UserName)
	loc_pwd.SendKeys(global.GVA_CONFIG.ApolloLogin.Password)

	updatePWDSql := ""
	resoverPWDSql := ""
	if global.GVA_CONFIG.ApolloLogin.UserName == "apollo" {
		var appolloUserInfo ApolloUsers
		var adminUserInfo ApolloUsers
		DB1.Raw(fmt.Sprintf("select * from users where Username='apollo'")).Scan(&appolloUserInfo)
		DB1.Raw(fmt.Sprintf("select * from users where Username='developer'")).Scan(&adminUserInfo)
		fmt.Println("apollo 用户信息", appolloUserInfo)
		fmt.Println("developer 用户信息", adminUserInfo)
		if len(appolloUserInfo.Username) > 0 && len(adminUserInfo.Username) > 0 {
			updatePWDSql = fmt.Sprintf("UPDATE `users` SET `Password` = '%s' where `id`=%d", adminUserInfo.Password, appolloUserInfo.Id)
			resoverPWDSql = fmt.Sprintf("UPDATE `users` SET `Password` = '%s' where `id`=%d", appolloUserInfo.Password, appolloUserInfo.Id)
			fmt.Println("更新SQL:", updatePWDSql)
			fmt.Println("恢复SQL:", resoverPWDSql)
			DB1.Exec(updatePWDSql)
		}
	}

	loc_submit.Click()

	if resoverPWDSql != "" {
		DB1.Exec(resoverPWDSql)
	}

	defer func() {
		if global.GVA_CONFIG.ApolloLogin.UserName == "apollo" {
			DB1.Close()
		}
		driverClean()
		fmt.Println("打开成功！")
	}()
}

func initDb() {
	if db, err := gorm.Open("mysql", global.GVA_CONFIG.ApolloLogin.Apollodb); err != nil {
		panic(err)
	} else {
		db.DB().SetMaxIdleConns(1)
		db.DB().SetMaxOpenConns(1)
		db.LogMode(true)
		DB1 = db
	}
}

func getRandomPort() (int, error) {
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return 0, err
	}
	defer listener.Close()
	return listener.Addr().(*net.TCPAddr).Port, nil
}

// https://registry.npmmirror.com/binary.html?path=chrome-for-testing/
func initDriver() (selenium.WebDriver, func()) {
	//ServiceOption 配置服务实例
	opts := []selenium.ServiceOption{
		//selenium.Output(os.Stderr), // Output debug information to STDERR.
	}
	//SetDebug 设置调试模式
	selenium.SetDebug(false)

	//pwd, _ := os.Getwd()
	driverName := "chromedriver"
	//if runtime.GOOS == "darwin" {
	//	_, filename, _, _ := runtime.Caller(0)
	//	//fmt.Println(pwd)
	//	pwd = filepath.Dir(filename)
	//	driverName = "chromedriver-mac"
	//}
	//fmt.Println(pwd + string(os.PathSeparator) + driverName)
	//在后台启动一个ChromeDriver实例
	//service, err := selenium.NewChromeDriverService(pwd+string(os.PathSeparator)+driverName, 18082, opts...)
	//driverName = "chromedriver"
	// 获取随机端口
	port, err := getRandomPort()
	if err != nil {
		panic(fmt.Sprintf("获取随机端口失败: %v\n", err))
	}
	fmt.Println(fmt.Sprintf("port：%d\n", port))

	service, err := selenium.NewChromeDriverService(driverName, port, opts...)
	if err != nil {
		service.Stop()
		panic(err) // panic is used only as an example and is not otherwise recommended.
	}

	caps := selenium.Capabilities{"browserName": "chrome"}
	detach := true
	chromeCaps := chrome.Capabilities{
		Args: []string{
			//"--headless", //设置Chrome无头模式
		},
		Detach: &detach, //driver是否自动关闭
		//ExcludeSwitches: []string{"enable-automation"}, //去除显示自动化提示
	}

	caps.AddChrome(chromeCaps)
	//caps.SetLogLevel(log.Profiler, log.Off)

	wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", port))
	if err != nil {
		service.Stop()
		wd.Quit()
		panic(err)
	}
	//
	wd.ResizeWindow("chrome", 1920, 1080)
	//wd.MaximizeWindow("chrome")
	return wd, func() {
		service.Stop()
		wd.Quit()
	}
	//defer wd.Quit()
}
